<?php
/**
 * @package Metamap Wrapper for Metamap (by Alan Aronson)
 * @copyright 2010
 * @author Herman Tolentino, MD (herman.tolentino@gmail.com)
 * @version 0.1
 * @license GPL 2.0
 * @example: 
 * 
 * <?php
 * $mm = new Metamap;
 * $mm->setMetamapHomeDir('/path/to/public_mm');
 * $mm->setMetamapBinary('metamap09');
 * $mm->getServerStatus();
 * if ($mm->bool_taggerServerUp) {
 *     print "taggerServer is up<br>\n";
 * }
 * if ($mm->bool_WSDServerUp) {
 *     print "WSDServer is up<br>\n";
 * }
 * $mm->setMappingText('avian influenza')
 *     ->setXMLOutput(true,'noformat')
 *     ->excludeSources('MSH')
 *     ->maptext();
 * ?>
 * 
 * Requirements: Metamap installed on local server. See Metamap web site for instructions.
**/
Class Metamap {
	
	public $bool_taggerServerUp = false;
	public $bool_WSDServerUp = false;
	public $metamapHomeDir = '';
	public $bool_HomeDirContentsComplete = false;
	public $textForAnnotation = '';
	public $metamapBinary = '';
	public $bool_XMLOutput = false;
	public $format_XMLOutput = 'format';
	public $sourcesForExclusion = '';
	
	public function __construct() {
		return $this;
	}
	
	public function setMetamapHomeDir($homedir='') {
		$this->metamapHomeDir = $homedir;
		$this->checkHomeDirContents($homedir);
		if ($this->bool_HomeDirContentsComplete) {
			print "Metamap home directory is ".$this->metamapHomeDir."<br>\n";
		} else {
			print "Error looking up metamap files<br>\n";
		}
		return $this;
	}
	
	public function setMetamapBinary($binaryname = '') {
		$this->metamapBinary = $binaryname;
	}
	
	private function checkHomeDirContents($homedir) {
		$metamap_binary = $this->metamapHomeDir.'/bin/metamap09';
		$tagger_binary = $this->metamapHomeDir.'/bin/skrmedpostctl';
		$wsdserver_binary = $this->metamapHomeDir.'/bin/wsdserverctl';
		if (file_exists($metamap_binary) && file_exists($tagger_binary) && file_exists($wsdserver_binary)) {
			$this->bool_HomeDirContentsComplete = true;
			return $this;
		} else {
			if (!file_exists($metamap_binary)) {
				print "Metamap executable is missing<br>\n";
			}
			if (!file_exists($tagger_binary)) {
				print "Part of speech tagger executable is missing<br>\n";
			}
			if (!file_exists($wsdserver_binary)) {
				print "Word sense disambiguator executable is missing<br>\n";
			}
		}
	}
	
	public function startTaggerServer() {
		$metamap_home = $this->metamapHomeDir;
		$buffer = `$metamap_home/bin/skrmedpostctl start 2>&1 1> /dev/null`;		
	}
	
	public function stopTaggerServer() {
		$metamap_home = $this->metamapHomeDir;
		$buffer = `$metamap_home/bin/skrmedpostctl stop 2>&1 1> /dev/null`;		
	}
	
	public function startWSDServer() {
		$metamap_home = $this->metamapHomeDir;
		$buffer = `$metamap_home/bin/wsdserverctl start 2>&1 1> /dev/null`;		
	}
	
	public function stopWSDServer() {
		$metamap_home = $this->metamapHomeDir;
		$buffer = `$metamap_home/bin/wsdserverctl stop 2>&1 1> /dev/null`;		
	}

	public function getServerStatus() {
		$buffer = `ps -ef | grep java`;
		if (preg_match("/taggerServer/m",$buffer)) {
			$this->bool_taggerServerUp = true;
		} else {
			$this->startTaggerServer();
		}
		if (preg_match("/wsd\.server\.DisambiguatorServer/m",$buffer)) {
			$this->bool_WSDServerUp = true;
		} else {
			$this->startWSDServer();
		}
		return $this;
	}
	
	public function setMappingText($text='') {
		$this->textForAnnotation = $text;
		return $this;
	}
	
	/**
	 * (--XML) <option> generate XML output. Default is plain text output.
	 * Options are format, noformat, format1, and noformat1. 
	 * The options format and format1 provide formatted, pretty-printed XML output, 
	 * while noformat and noformat1 provide a concise, unformatted XML output. 
	 * See ''MetaMap 2009 Release Notes'' (http://metamap.nlm.nih.gov/MM09__Release__Notes.shtml) 
	 * for more information.
	 * 
 	**/
	public function setXMLOutput($bool_XMLOutput = false, $format_XMLOutput = 'format') {
		$this->bool_XMLOutput = $bool_XMLOutput;
		$this->format_XMLOutput = $format_XMLOutput;
		return $this;
	}
	
	/**
	 * -e (--exclude_sources) <list> excludes those sources in the 
	 * comma-separated <list> where spaces are not allowed.
	 * 
 	**/
	public function excludeSources($sourcesForExclusion = '') {
		if (strlen(trim($sourcesForExclusion))>0) {
			$this->sourcesForExclusion = $sourcesForExclusion;
			return $this;
		}
	}
 	
	public function maptext() {
		$metamap_home = $this->metamapHomeDir;
		$metamap_binary = $this->metamapBinary;
		$metamap_text = $this->textForAnnotation;
		$options = '';
		if ($this->bool_XMLOutput) {
			$format_XMLOutput = $this->format_XMLOutput;
			$options = $options." --XML $format_XMLOutput";
		}
		if (strlen(trim($this->sourcesForExclusion))>0) {
			$sourcesForExclusion = $this->sourcesForExclusion;
			$options = $options." --exclude_sources $sourcesForExclusion";
		}
		print $buffer = `echo $metamap_text | $metamap_home/bin/$metamap_binary $options`;
	}
	
}
?>
